package com.zj.executor.statement;

import com.zj.executor.result.ResultHandler;
import com.zj.executor.result.SimpleResultHandler;
import com.zj.mapping.BoundSql;
import com.zj.mapping.Configration;
import com.zj.mapping.MappedStatement;
import com.zj.reflect.ReflectUtil;
import com.zj.utils.ParameterMapping;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.List;

public class PreparedStatementHandler implements StatementHandler {

    private Configration configration;

    public PreparedStatementHandler(Configration configration) {
        this.configration = configration;
    }

    @Override
    public <E> List<E> query(MappedStatement mappedStatement, BoundSql boundSql, ResultHandler resultHandler, Object... params) throws Exception {
        //获取数据库连接
        Connection connection = configration.getDataSource().getConnection();
        //获取预编译对象并且进行参数赋值
        PreparedStatement preparedStatement = getPreparedStatementAndParameterize(
                mappedStatement,
                boundSql,
                connection,
                params);
        //执行sql
        ResultSet resultSet = preparedStatement.executeQuery();
        //创建并委托SimpleResultHandler，进行结果集处理，并返回结果
        return new SimpleResultHandler().handle(resultSet, mappedStatement);
    }

    @Override
    public Integer update(MappedStatement mappedStatement, BoundSql boundSql,Object... params) throws Exception {
        //获取数据库连接
        Connection connection = configration.getDataSource().getConnection();
        //获取预编译对象并且进行参数赋值
        PreparedStatement preparedStatement = getPreparedStatementAndParameterize(
                mappedStatement,
                boundSql,
                connection,
                params);

        return preparedStatement.executeUpdate();
    }

    //获取预编译对象，并且对占位符赋值
    private PreparedStatement getPreparedStatementAndParameterize(MappedStatement mappedStatement, BoundSql boundSql, Connection connection, Object... params) throws Exception {
        PreparedStatement preparedStatement = connection.prepareStatement(boundSql.getSqlText());
        //占位符赋值
        String paramterType = mappedStatement.getParamterType();
        Class paramterClass = ReflectUtil.getClassByType(paramterType);
        List<ParameterMapping> parameterMappingList = boundSql.getParameterMappingList();
        //一一赋值
        for (int i = 0; i < parameterMappingList.size(); i++) {
            String content = parameterMappingList.get(i).getContent();
            Object fieldValue = ReflectUtil.getFieldValue(paramterClass, content, params[0]);
            preparedStatement.setObject(i + 1, fieldValue);
        }
        return preparedStatement;
    }


}
